package model

import java.net.MalformedURLException;
import java.util.Date
import javax.swing.SwingUtilities;





import com.mysql.jdbc.jdbc2.optional.MysqlDataSource

import groovy.sql.Sql

import java.io.IOException;
import java.net.URL;
import java.net.URLConnection;
import java.sql.*




class LinkChecker implements CrawlerInterface, Runnable{
	protected URL url
	protected int goodLinks = 0
	protected int badLinks = 0
	protected Crawler crawler
	protected Thread backgroundThread;
	protected Thread timeThread;
	protected programTerminator = true
	MysqlDataSource ds
	protected Sql data
	synchronized String errorMessage = ""
	protected Time s
	static int table
	String requestCode
	LinkChecker(URL url){
		ds = new MysqlDataSource()
		ds.user = 'root'
		ds.password='root'
		ds.url='jdbc:mysql://localhost/forager'
		data = new Sql(ds)

		this.url=url
		/**crawler = new Crawler(this)
		 crawler.addURL(url)
		 crawler.start();
		 */


	}
	void begin(){
		programTerminator=true
		if ( backgroundThread==null ) {

			backgroundThread = new Thread(this);
			backgroundThread.start();
			goodLinks=0;
			badLinks=0;
			String dateTime = new Date()
			CrawlerInfo.crawlerRunningStatus=true;
			data.execute"update tablenumber set dateTime=${dateTime} where tables in (${table})"
		} else {
			crawler.terminate();
		}
		if(timeThread==null)
		{	
			s=new Time()
			timeThread = new Thread(s)
			timeThread.start()
		} else {
			s=new Time()
			timeThread = new Thread(s)
			timeThread.start()
		}
		
				
			
		
		/**s = new Time()
		 s.start()
		 crawler = new Crawler(this)
		 crawler.clear()
		 crawler.addURL(url)
		 crawler.start()*/
	}

	@Override
	boolean urlFound(URL host, URL url) {
		UpdateStatus()
		if(crawler.terminator)
			return true
		if ( !checkLink(url) ) {
			if(programTerminator==false)
				return
			String first = url.toString()
			String second = host.toString()
			data.execute"insert into table${table} values(${first},${errorMessage},${second})"
			/*data.execute"insert into links(error) values(404)"
			 data.execute"insert into links(pageLink) values(${second})"*/

			badLinks++
			return false
		}

		goodLinks++;
		if ( !url.getHost().equalsIgnoreCase(host.getHost()) )
			return false
		else
			return true
	}

	@Override
	void urlError(URL url) {
		System.out.println("Found url Error: " + url.toString())

	}

	@Override
	void foundEMail(String email) {
		
	}

	boolean checkLink(URL url)
	{ 	if(programTerminator==false)
			return
		
		try{
			
		Thread.sleep(10)
		HttpURLConnection connection = url.openConnection()
		connection.setRequestMethod ("GET");
		connection.connect()
		int code = connection.getResponseCode()
		requestCode=""+code
		connection.disconnect()
		if(code >= 200 && code<400)
			return true
		else if(code==404 || code == 400){
			errorMessage=code
			return false
		} else 
			return true
		} catch (IOException e){
			if(e.getMessage().contains("Server redirected"))
				return true
			if(e.getMessage().contains("handshake alert"))
				return true
			if(e.getMessage().contains("connect")){
				Thread.sleep(40)
				return checkLink(url)
			}
			if(e.getMessage().contains(url.getHost()))
				return true
			errorMessage=e.getMessage()
			return false
		}

		


	}
	void stopScan(){
		crawler.clear()
		crawler.terminate()
		programTerminator=false
		String stopStatusString = "Terminated by the user"
		data.execute"update tablenumber set goodLink=${CrawlerInfo.getGood()} where tables in (${table})"
		data.execute"update tablenumber set badLink=${CrawlerInfo.getBad()} where tables in (${table})"
		data.execute"update tablenumber set timeElapsed=${CrawlerInfo.getTimeElapsed()} where tables in (${table})"
		data.execute"update tablenumber set status=${stopStatusString} where tables in (${table})"

	}
	void UpdateStatus(){
		
		//crawler.log("Good Links: "+goodLinks+" Bad Links " + badLinks +" Time Elapsed " + s.getTime() + " processed " +crawler.getProcessedQueue().size())
		if(programTerminator==false){
			data.execute"update tablenumber set goodLink=${CrawlerInfo.getGood()} where tables in (${table})"
			data.execute"update tablenumber set badLink=${CrawlerInfo.getBad()} where tables in (${table})"
			data.execute"update tablenumber set timeElapsed=${CrawlerInfo.getTimeElapsed()} where tables in (${table})"
		}
		
		
	}

	class Time implements Runnable {
		public long startTime;
		public long endTime;
		String time
		public void update() {
			stop()
			
			long temp = endTime - startTime
			temp=temp/1000
			if(temp>=3600)
				time=""+(int)(temp/3600)+" hours "+(int)((temp%3600)/60)+" mins "+ (int)((temp%3600)%60)+" secs"
			else if(temp>=60)
				time=""+(int)(temp/60)+" mins "+ (int)(temp%60)+" secs"
			else time=""+temp+" secs"

			
		}
		// I  would add
		public Time() {
			startTime = System.currentTimeMillis();
		}
		public void stop() {
			endTime = System.currentTimeMillis();
		}
		public String getTime(){
			return time
		}
		@Override
		public void run() {
			while(programTerminator){
				update()
				CrawlerInfo.good=goodLinks
				CrawlerInfo.bad=badLinks
				CrawlerInfo.timeElapsed=s.getTime()
				CrawlerInfo.webpageProcessed = crawler.getProcessedQueue().size()
			}
			startTime=0
			endTime=0
			
		}
	}

	@Override
	public void run() {
		try {
			
			
			//s = new Time()
			//s.start()
			crawler = new Crawler(this);
			crawler.clear();

			crawler.addURL(url);
			crawler.start();

			backgroundThread=null;

		} catch ( MalformedURLException e ) {

			println("Malformed URL:" + e.getMessage())

		}

	}
	
	public static void setTable(int number) {
		this.table = number;
	}
	
	public static int isTable(){
		
		return table;
	}
	@Override
	public void scanFinished() {
		programTerminator=false
		String stopStatusString = "Full Scan completed"
		data.execute"update tablenumber set goodLink=${CrawlerInfo.getGood()} where tables in (${table})"
		data.execute"update tablenumber set badLink=${CrawlerInfo.getBad()} where tables in (${table})"
		data.execute"update tablenumber set timeElapsed=${CrawlerInfo.getTimeElapsed()} where tables in (${table})"
		data.execute"update tablenumber set status=${stopStatusString} where tables in (${table})"
		
	}
	
}
